package framework.proxy
{
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.text.TextField;
import flash.utils.Dictionary;

import framework.core.ComponentBuilder;
import framework.injection.IInjectable;
import framework.view.components.button.ButtonProxy;
import framework.view.components.button.StateButtonProxy;
import framework.view.components.container.RepeaterProxy;

import mx.utils.UIDUtil;

/**
 * ComponentProxy
 * @author jliang
 * 
 */
public class ComponentProxy extends EventDispatcher implements IComponentProxy, IInjectable
{
	//==========================================================================
	//  Constructor
	//==========================================================================
	public function ComponentProxy()
	{
		super();
	}
	//==========================================================================
	//  Properties
	//==========================================================================
	protected var _id:String = UIDUtil.createUID();
	
	public function get id():String
	{
		return _id;
	}
	
	public function set id(value:String):void
	{
		_id = value;
	}
	
	public function set visible(value:Boolean):void
	{
        skinContent.visible = value;
	}
	
	public function get visible():Boolean
	{
		return skinContent.visible;
	}
	
	protected var skin:MovieClip;
	
	public function get skinContent():MovieClip
	{
		return skin;
	}
	
	public function get skinContainer():DisplayObjectContainer
	{
		return skin ? skin.parent : null;
	}
	
	protected var _orignalContainer:DisplayObjectContainer
	
	public function get orignalContainer():DisplayObjectContainer
	{
		return _orignalContainer;
	}
    
    public function set x(value:Number):void
    {
        skinContent.x = value;
    }
    
    public function get x():Number
    {
        return skinContent.x;
    }
    
    public function set y(value:Number):void
    {
        skinContent.y = value;
    }
    
    public function get y():Number
    {
        return skinContent.y;
    }
    
    public function set alpha(value:Number):void
    {
        skinContent.alpha = value;
    }
    
    public function get alpha():Number
    {
        return skinContent.alpha;
    }
	
	protected var proxys:Dictionary; /* ComponentProxy */
	
	protected function get proxyMapping():Array
	{
		return [];
	}
	//==========================================================================
	//  Public methods
	//==========================================================================
	public function parse(target:MovieClip):void
	{
		skin = target;
		
		if (skin)
		{            
			if (!skin.stage)
			{
				skin.addEventListener(Event.ADDED_TO_STAGE, addToStageHandler);
			}
			if (skin.parent) _orignalContainer = skin.parent;
			
			var temp:Array = proxyMapping;
			for each (var proxyDef:Object in temp)
			{				
				var def:Array = String(proxyDef.skin).split(".");
				var tempSkin:DisplayObject = skin;
				for (var i:int = 0; i < def.length; i++)
				{
					tempSkin = (def[i] != "" ? tempSkin[def[i]] : skin);
				}
				
				if (tempSkin is TextField && proxyDef.hasOwnProperty("text"))
				{
					TextField(tempSkin).text = proxyDef.text;
				}
				
				if (proxyDef.hasOwnProperty("classRef"))
				{
					var proxyRef:Class = proxyDef.classRef as Class;
					var proxy:IComponentProxy = ComponentBuilder.create(proxyRef);
					
					if (proxy is RepeaterProxy)
					{
						if (proxyDef.hasOwnProperty("renderProxyRef"))
						{
							RepeaterProxy(proxy).renderProxyRef = proxyDef.renderProxyRef as Class;
						}
						if (proxyDef.hasOwnProperty("onItemSelected"))
						{
							RepeaterProxy(proxy).onItemSelected = proxyDef.onItemSelected as Function;
						}
					}
					
					if (proxyDef.method) 
					{
						proxy[proxyDef.method](tempSkin);
					}
					else
					{
						proxy.parse(tempSkin as MovieClip);
					}
					
					if (proxy is ButtonProxy)
					{
						if (proxyDef.hasOwnProperty("onClick"))
						{
							ButtonProxy(proxy).onClick = proxyDef.onClick as Function;
						}
						if (proxyDef.hasOwnProperty("onMouseOut"))
						{
							ButtonProxy(proxy).onMouseOut = proxyDef.onMouseOut as Function;
						}
						if (proxyDef.hasOwnProperty("onMouseOver"))
						{
							ButtonProxy(proxy).onMouseOver = proxyDef.onMouseOver as Function;
						}
					}
					
					if (proxy is StateButtonProxy)
					{
						if (proxyDef.hasOwnProperty("onSelected"))
						{
							StateButtonProxy(proxy).onSelected = proxyDef.onSelected as Function;
						}
						if (proxyDef.hasOwnProperty("onMouseOut"))
						{
							StateButtonProxy(proxy).onMouseOut = proxyDef.onMouseOut as Function;
						}
						if (proxyDef.hasOwnProperty("onMouseOver"))
						{
							StateButtonProxy(proxy).onMouseOver = proxyDef.onMouseOver as Function;
						}
					}
					
					if (Object(proxy).hasOwnProperty("text") && proxyDef.hasOwnProperty("text"))
					{
						proxy["text"] = proxyDef.text;
					}
					
					if (!proxys) proxys = new Dictionary(true);
					if (!proxyDef.id)
					{
						proxyDef.id = UIDUtil.createUID();
					}
					proxys[proxyDef.id] = proxy;
					proxy.id = proxyDef.id;
				}
				
			}
		}
	}
	
	public function dispose():void
	{
		if (skin) 
		{
			skin.removeEventListener(Event.ADDED_TO_STAGE, addToStageHandler);
			skin.removeEventListener(Event.REMOVED_FROM_STAGE, removeFromStageHandler);
		}
		
		for each (var proxy:IComponentProxy in proxys)
		{
			proxy.dispose();
		}
		
		proxys = null;
	}
	
	protected function addToStageHandler(event:Event):void
	{
		skin.addEventListener(Event.REMOVED_FROM_STAGE, removeFromStageHandler);
		
		if (!_orignalContainer)
		{
			_orignalContainer = skin.parent;
		}
	}
	
	protected function removeFromStageHandler(event:Event):void
	{
		skin.removeEventListener(Event.REMOVED_FROM_STAGE, removeFromStageHandler);
	}
}
}